#![allow(unused_macros)]
#![allow(unused_attributes)]
#![macro_export]

use crate::wdlog::log_entity::*;
use lazy_static::*;
use std::io;
use std::sync::Mutex;

pub const PANIC: Level = 1;
pub const ERROR: Level = 2;
pub const WARN: Level = 3;
pub const INFO: Level = 4;
pub const DEBUG: Level = 5;

lazy_static! {
    pub static ref LOG: Mutex<LogEntity> = Mutex::new(LogEntity::new());
}

pub fn set_level(level: Level) {
    let l = LOG.lock();
    if let Ok(mut log) = l {
        log.set_level(level)
    }
}
pub fn set_prefix(prefix: String) {
    let l = LOG.lock();
    if let Ok(mut log) = l {
        log.set_prefix(prefix)
    }
}
pub fn set_time_print(ok: bool) {
    let l = LOG.lock();
    if let Ok(mut log) = l {
        log.set_time_print(ok)
    }
}
pub fn set_file_line(ok: bool) {
    let l = LOG.lock();
    if let Ok(mut log) = l {
        log.set_file_line(ok)
    }
}
pub fn output_to_file(path: &str) -> io::Result<()> {
    let l = LOG.lock();
    if let Ok(mut log) = l {
        return log.output_to_file(path);
    }
    Ok(())
}

macro_rules! output {
    ($level:expr,$ctx:expr,$file:expr,$line:expr) => {
        match $crate::wdlog::log::LOG.lock() {
            Err(e) => {
                println!("日志模块错误:{:?}", e);
            }
            Ok(mut log) => {
                log.output_file_line($level, $ctx, $file, $line);
            }
        }
    };
}

macro_rules! log_debug_f {
    ($($arg:tt)*) => ({
    let line = line!();
        let file = file!();
        let value = format!($($arg)*);
        output!($crate::wdlog::log::DEBUG,&value,file,line);
    })
}

macro_rules! log_debug_ln {
    ($($arg:tt)*) => ({
        let line = line!();
        let file = file!();
        let mut value = format!($($arg)*);
        value.push_str("\n");
        output!($crate::wdlog::log::DEBUG,&value,file,line);
    })
}

macro_rules! log_info_f {
    ($($arg:tt)*) => ({
    let line = line!();
            let file = file!();
            let value = format!($($arg)*);
            output!($crate::wdlog::log::INFO,&value,file,line);
    })
}

macro_rules! log_info_ln {
    ($($arg:tt)*) => ({
        let line = line!();
        let file = file!();
        let mut value = format!($($arg)*);
        value.push_str("\n");
        output!($crate::wdlog::log::INFO,&value,file,line);
    })
}

macro_rules! log_warn_f {
    ($($arg:tt)*) => ({
    let line = line!();
        let file = file!();
        let value = format!($($arg)*);
            output!($crate::wdlog::log::WARN,&value,file,line);
    })
}

macro_rules! log_warn_ln {
    ($($arg:tt)*) => ({
    let line = line!();
        let file = file!();
        let mut value = format!($($arg)*);
        value.push_str("\n");
        output!($crate::wdlog::log::WARN,&value,file,line);
    })
}

macro_rules! log_error {
    ($result:expr;$($arg:tt)*) => ({
        match $result {
            Err(e)=>{
                let line = line!();
                let file = file!();
                let mut value = format!($($arg)*);
                let error = format!(" error:{}",e);
                value.push_str(&error);
                value.push_str("\n");
                output!($crate::wdlog::log::ERROR,&value,file,line-2);
                (None,false)
            }
            Ok(res)=>{
                (Some(res),true)
            }
        }
    })
}

macro_rules! log_error_f {
    ($($arg:tt)*) => ({
    let line = line!();
        let file = file!();
        let value = format!($($arg)*);
        output!($crate::wdlog::log::ERROR,&value,file,line);
    })
}

macro_rules! log_error_ln {
    ($($arg:tt)*) => ({
    let line = line!();
        let file = file!();
        let mut value = format!($($arg)*);
        value.push_str("\n");
        output!($crate::wdlog::log::ERROR,&value,file,line);
    })
}

// macro_rules! log_panic {
//     ($($arg:tt)*) => ({
//         let value = format!($($arg)*);
//         output!($crate::wdlog::log::PANIC,value,file,line);
//     })
// }

macro_rules! log_panic {
    ()=>{panic!();};
    ($($arg:tt)*)=>{
         let line = line!();
         let file = file!();
         let mut value = format!($($arg)*);
         value.push_str("\n");
         output!($crate::wdlog::log::PANIC,&value,file,line);
         panic!(value);
    };
}
macro_rules! log_panic_result {
    ($result:expr)=>{
        match $result {
            Err(e)=>{
                let line = line!();
                let file = file!();
                let mut error = format!(" error:{:?}",e);
                error.push_str("\n");
                output!($crate::wdlog::log::PANIC,&error,file,line-2);
                panic!(error);
            }
            Ok(res)=>{
               res
            }
        }
    };
    ($result:expr;$($arg:tt)*) => ({
        match $result {
            Err(e)=>{
                let line = line!();
                let file = file!();
                let mut value = format!($($arg)*);
                let error = format!(" error:{}",e);
                value.push_str(&error);
                value.push_str("\n");
                output!($crate::wdlog::log::PANIC,value,file,line-2);
                panic!(error);
            }
            Ok(res)=>{
               res
            }
        }
    });
}
